#include "Graph_2.h"

namespace Graph_lib{

	Arc::Arc(Point p, int w, int h, double d, double d1):degree_s(d), degree_e(d1), width(w), height(h) 
	{
		add(Point(p.x-w/2, p.y-h/2));
	}

	Point Arc::center() const
	{
		return Point(point(0).x+width/2, point(0).y+height/2);
	}


	void Arc::draw_lines() const
	{
		if (color().visibility())
			fl_arc(point(0).x, point(0).y, width, height, degree_s, degree_e);
	}

	void Box::draw_lines() const
	{
		if (fill_color().visibility())
			draw_fill();
		if (color().visibility()){
			draw_empty();
		}
	}

	void Box::draw_empty() const
	{
		fl_color(color().as_int());
		fl_line(point(0).x+r, point(0).y,point(0).x+w-r, point(0).y); 
		fl_arc(point(0).x, point(0).y, 2*r, 2*r, 90, 180);
		fl_line(point(0).x+r, point(0).y+h,point(0).x+w-r, point(0).y+h);
		fl_arc(point(0).x+w-2*r, point(0).y, 2*r, 2*r, 0, 90);
		fl_line(point(0).x, point(0).y+r, point (0).x, point(0).y+h-r); 
		fl_arc(point(0).x, point(0).y+h-2*r, 2*r, 2*r,180, 270);
		fl_line(point(0).x+w, point(0).y+r, point (0).x+w, point(0).y+h-r);
		fl_arc(point(0).x+w-2*r, point(0).y+h-2*r, 2*r, 2*r,270, 360);
	}
	void Box::draw_fill() const
	{
		fl_color(fill_color().as_int());
		fl_rectf(point(0).x+r, point(0).y, w-2*r, h);
		fl_rectf(point(0).x,   point(0).y+r, w, h-2*r);
		fl_pie(point(0).x, point(0).y, 2*r, 2*r, 0, 360);
		fl_pie(point(0).x+w-2*r, point(0).y, 2*r, 2*r, 0, 360);
		fl_pie(point(0).x, point(0).y+h-2*r, 2*r, 2*r, 0, 360);
		fl_pie(point(0).x+w-2*r, point(0).y+h-2*r, 2*r, 2*r,0, 360);
	}


	void Arrow::draw_lines() const
	{
		if (color().visibility()){
			double dx0  = point(0).x;
			double dx1  = point(1).x;
			double dy0  = point(0).y;
			double dy1  = point(1).y;
			
			double fi   = atan((dy1-dy0)/(dx1-dx0));
			double fi_l = fi+PI/6;
			double fi_r = fi-PI/6;

			double dx_l = arrow_size*cos(fi_l);
			double dy_l = arrow_size*sin(fi_l);
			
			double dx_r = arrow_size*cos(fi_r);
			double dy_r = arrow_size*sin(fi_r);
						
			double dx_c = arrow_size*cos(fi)*abs(cos(fi-fi_r));
			double dy_c = arrow_size*sin(fi)*abs(cos(fi-fi_r));
						
			if (dx0 <= dx1)
			{
				dx_l*=-1;
				dx_r*=-1;
				dx_c*=-1;

				dy_l*=-1;
				dy_r*=-1;
				dy_c*=-1;
			}
			
			
			fl_line(int(dx1+dx_c), int(dy1+dy_c), point(0).x, point(0).y);
			fl_line(point(1).x, point(1).y,	int(dx1+dx_l), int(dy1+dy_l));
			fl_line(point(1).x, point(1).y,	int(dx1+dx_r), int(dy1+dy_r));
			fl_line(int(dx1+dx_l), int(dy1+dy_l),int(dx1+dx_r), int(dy1+dy_r));

			
		}
	}

	BoxWithText::BoxWithText(Point xy, int ww, int hh, int rr, const string& ss)
		:tt(Point(xy.x + ww/10, xy.y + hh/2),ss), Box(xy,ww,hh,rr) 
	{}

	void BoxWithText::draw_lines()  const
	{
		Box::draw_lines();
		tt.draw_lines();
	}
}